package torrentfile

import (
	"BTClient/peers"
	"bytes"
	"errors"
	"fmt"
	"github.com/jackpal/bencode-go"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"strconv"
	"time"
)

// Port to listen on 监听端口
const Port uint16 = 6882

type bencodeTrackerResp struct {
	Interval int    `bencode:"interval"`
	Peers    string `bencode:"peers"`
}

// buildTrackerURL 构建追踪器的url
// peerID 下载者的标识符
func (t *TorrentFile) buildTrackerURL(peerID [20]byte, port uint16) (*url.URL, error) {
	base, err := url.Parse(t.Announce)
	if err != nil {
		return &url.URL{}, err
	}

	params := url.Values{
		"info_hash":  []string{string(t.InfoHash[:])},
		"peer_id":    []string{string(peerID[:])},
		"port":       []string{strconv.Itoa(int(Port))},
		"uploaded":   []string{"0"},
		"downloaded": []string{"0"},
		"compact":    []string{"1"},
		"left":       []string{strconv.Itoa(t.Length)},
	}
	base.RawQuery = params.Encode()
	return base, nil
}

// requestPeers 获取 peers
func (t *TorrentFile) requestPeers(peerID [20]byte, port uint16) error {
	// 构建URL
	base, er := t.buildTrackerURL(peerID, port)
	if er != nil {
		return er
	}

	fmt.Println(base)

	switch base.Scheme {
	case "http", "https":
		c := &http.Client{Timeout: 30 * time.Second}
		resp, err := c.Get(base.String())
		if err != nil {
			return err
		}
		defer resp.Body.Close()

		trackerResp := bencodeTrackerResp{}
		all, err := ioutil.ReadAll(resp.Body)

		err = bencode.Unmarshal(bytes.NewReader(all), &trackerResp)
		if err != nil {
			return err
		}
		t.Peers, err = peers.Unmarshal([]byte(trackerResp.Peers))
		return err
	case "udp":
		// host ip:port
		_, err := net.Dial("udp", base.Host)
		if err != nil {
			fmt.Println(err)
			return err
		}

		return nil
	default:
		return errors.New("未适配的协议")
	}
}
